<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);

namespace app\common\library\wechat;

use app\api\service\user\Avatar as AvatarService;
use app\api\model\User as UserModel;
use think\facade\Cache;

/**
 * 微信小程序用户管理类
 * Class WxUser
 * @package app\common\library\wechat
 */
class WxgUser extends WxgBase
{
    /**
     * 获取openid和微信用户信息
     * @return array
     * @throws \app\common\exception\BaseException
     */
    public function jscode2openidWxinfo():array
    {
        $r = $this->getAccessToken();
        $rArr = $r['rArr'];
        $openid = $rArr['openid'];
        $access_token = $rArr['access_token'];
        $wxInfo = $this->getWxInfo($openid,$access_token);
        if(array_key_exists('errcode',$wxInfo)){
            throwError("微信公众号userInfo获取失败，错误信息：{$wxInfo}");
        }
        if(!array_key_exists('nickname',$wxInfo)){
            throwError('请以snsapi_userinfo为scope发起的网页授权!',500);
        }
        return [
            'openid' => $openid,
            'wxInfo' => $wxInfo
        ];
    }

    /**
     * 获取openid unionid
     * @param int $user_id
     * @return array
     * @throws \app\common\exception\BaseException
     */
    public function jscode2openid2(int $user_id):array
    {
        $cacheKey = $this->appId . '@wxg_openid_access_token'.$user_id;
        if (!Cache::instance()->get($cacheKey)) {
            $rArr = $this->getAccessToken();
            // 写入缓存
            Cache::instance()->set($cacheKey, $rArr['rJson'], 6000);
        }
        $rJson = Cache::instance()->get($cacheKey);
        $rArr = $this->jsonDecode($rJson);
        $openid = $rArr['openid'];
        $access_token = $rArr['access_token'];
        $get_user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN";
        $result = $this->get($get_user_info_url);
        $response = $this->jsonDecode($result);
        if (array_key_exists('errcode', $response)) {
            throwError("微信公众号userInfo获取失败，错误信息：{$result}");
        }
        // 新增或更新用户数据
        $this->partyUserInfo($response,$user_id);
        return [
            'openid' => $openid,
            'unionid' => $result['unionid'] ?? null
        ];
    }

    /**
     * 获取微信用户信息
     * @param string $openid
     * @param string $access_token
     * @return mixed
     * @throws \app\common\exception\BaseException
     */
    private function getWxInfo(string $openid,string $access_token){
        $get_user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN";
        $result = $this->get($get_user_info_url);
        return $this->jsonDecode($result);
    }

    /**
     * 第三方用户信息
     * @param array $partyData 第三方用户信息
     * @param bool $isGetAvatarUrl 是否下载头像
     */
    private function partyUserInfo(array $partyData, int $user_id)
    {
        $data = [
            'user_id' => $user_id,
            'nick_name' => base64_encode($partyData['nickname']),
            'gender' => $partyData['sex']
        ];
        // 下载用户头像
        if (!empty($partyData['headimgurl'])) {
            $data['avatar_id'] = $this->partyAvatar($partyData['headimgurl']);
        }
        // 写入用户数据
        // 新增用户记录
        return UserModel::update($data,['user_id'=>$user_id]);
    }

    /**
     * 下载第三方头像并写入文件库
     * @param string $avatarUrl
     * @return int
     */
    private function partyAvatar(string $avatarUrl)
    {
        $Avatar = new AvatarService;
        $fileId = $Avatar->party($avatarUrl);
        return $fileId ? $fileId:0;
    }
}
